﻿#include <stdio.h>
#include <string.h>
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"

#include "semphr.h"
#include "queue.h"

#include "uart_device.h"

#define UART_RECV_BUF 128

extern UART_HandleTypeDef huart5;

typedef struct UART_Data {
	UART_HandleTypeDef *huart;
	uint8_t recv_char;
	SemaphoreHandle_t xSendSemaphore;
	QueueHandle_t xRecvQueue;
}UART_Data, *P_UART_Data;

static UART_Data g_uart5_data = {
	&huart5,
};


void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	/* 释放信号量 */
	P_UART_Data pData;
	/* 把数据放入队列 */
	if (huart == &huart5)
	{
		pData = &g_uart5_data;
		xSemaphoreGiveFromISR(pData->xSendSemaphore, NULL);
	}	
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 	P_UART_Data pData;
	/* 把数据放入队列 */
	if (huart == &huart5)
	{
		pData = &g_uart5_data;
		xQueueSendFromISR(pData->xRecvQueue, &pData->recv_char, NULL);
		
		/* re-enable rxne interrupt */
		HAL_UART_Receive_IT(pData->huart, &pData->recv_char, 1);
	}	
}


int uart_init( struct UART_Device *pDev, int baud, char parity, int data_bit, int stop_bit)
{
 	P_UART_Data pData = pDev->priv_data;
	
	if (!pData->xSendSemaphore)
	{
		pData->xSendSemaphore = xSemaphoreCreateBinary( );
		pData->xRecvQueue = xQueueCreate(UART_RECV_BUF, 1);
	}

	/* 使能接收中断 */
	/* enable rxne interrupt */
	HAL_UART_Receive_IT(pData->huart, &pData->recv_char, 1);
	
    return 0;
}

int uart_send( struct UART_Device *pDev, uint8_t *datas, uint32_t len, int timeout)
{
 	P_UART_Data pData = pDev->priv_data;
    if (HAL_OK == HAL_UART_Transmit_IT(pData->huart, datas, len))  /* 触发"发送空中断",并不表示数据已经发送完毕 */
   	{
   		/* 等待信号量 */
		if (pdTRUE == xSemaphoreTake(pData->xSendSemaphore, timeout))			
	        return 0;
		else
			return -1;
	}
    else
        return -1;
}

int uart_recv( struct UART_Device *pDev, uint8_t *data, int timeout)
{
 	P_UART_Data pData = pDev->priv_data;

	/* 读队列 */
	if (pdPASS == xQueueReceive(pData->xRecvQueue, data, timeout))
		return 0;
	else
		return -1;
}

int uart_flush(struct UART_Device *pDev)
{
 	P_UART_Data pData = pDev->priv_data;
	uint8_t data;
	int i = 0;

	/* 读队列 */
	while (pdPASS == xQueueReceive(pData->xRecvQueue, &data, 0))
	{
		i++;
	}
	
    return i;
}


static struct UART_Device g_uart5_dev = {"uart5", uart_init, uart_send, uart_recv, uart_flush, &g_uart5_data};


static struct UART_Device *g_uart_devices[] = {&g_uart5_dev};


struct UART_Device *GetUARTDevice(char *name)
{
	int i = 0;
	for (i = 0; i < sizeof(g_uart_devices)/sizeof(g_uart_devices[0]); i++)
	{
		if (!strcmp(name, g_uart_devices[i]->name))		
			return g_uart_devices[i];
	}
	
	return NULL;
}
